package lapsnake.model.data;

import java.beans.PropertyVetoException;
import java.util.Iterator;

import lapsnake.model.LapNode;

public class OptionalChild<T extends LapNode> extends AbstractChildField<T>
{
	T value;
	public OptionalChild(LapNode owner, Class<T> childType)
	{
		this(owner, childType, true);
	}
	public OptionalChild(LapNode owner, Class<T> childType, boolean indented)
	{
		super(owner, childType, indented);
	}

	@Override
	public boolean isOptional()
	{
		return true;
	}
	
	@Override
	public int indexOf(LapNode n)
	{
		return value == n ? 0:-1;
	}

	@Override
	public boolean isList()
	{
		return false;
	}

	@Override
	public int size()
	{
		return value==null?0:1;
	}

	@Override
	public T get(int index)
	{
		if(index < 0 || index >=size())
			throw new IllegalArgumentException(this+" on "+getOwner()+": Index out of bounds: "+index+"/"+size());
		return value;
	}

	@Override
	public void set(int index, T child, Object exclude, boolean fireEvents)
		throws IllegalArgumentException, PropertyVetoException
	{
		checkVetos(exclude, value);
		if(index < 0 || index > 1)
			throw new IllegalArgumentException("Index out of bounds: "+index+"/1");
		this.value = child;
		if(fireEvents)
			fireEvents(exclude);
	}

	@Override
	public void remove(Object exclude, boolean fireEvents) throws PropertyVetoException, IllegalArgumentException
	{
		checkVetos(exclude, null);
		if(value == null)
			throw new IllegalArgumentException(this+" already does not have any value...");
		value = null;
		if(fireEvents)
			fireEvents(exclude);
	}	
	
	@Override
	public String toString()
	{
		return "Optional "+type.getSimpleName()+'('+size()+") on "+getOwner();
	}
	
	@Override
	public Iterator<T> iterator()
	{
		return new Iterator<T>()
		{
			boolean hasNext = !isEmpty();
			@Override
			public boolean hasNext()
			{
				return hasNext;
			}

			@Override
			public T next()
			{
				hasNext = false;
				return get();
			}
		};
	}
	
}
